var HTMLEdManager = {};

HTMLEdManager._instances = {};
HTMLEdManager._plugins = {};

HTMLEdManager.savedrange = null;

HTMLEdManager.getSelection = function  ( doc, editor )
{
	var savedRange;
	var fr = editor.iframe; //document.querySelector ( 'iframe' );
	if( fr.contentWindow.getSelection && fr.contentWindow.getSelection().rangeCount > 0) //FF,Chrome,Opera,Safari,IE9+
	{
		savedRange = fr.contentWindow.getSelection().getRangeAt(0).cloneRange();
	}
	else if(doc.selection)//IE 8 and lower
	{ 
		savedRange = doc.selection.createRange();
	}
	return savedRange;
}

HTMLEdManager.create = function ( name, txtarea_id, plugins )
{
	var htmled = new HTMLEd ( name, plugins );

	if ( txtarea_id ) htmled.replace ( txtarea_id );

	HTMLEdManager._instances [ name ] = htmled;

	return htmled;
};

HTMLEdManager.get = function ( name )
{
	return HTMLEdManager._instances [ name ];
};

HTMLEdManager.register_plugin = function ( name, plugin_data )
{
	HTMLEdManager._plugins [ name ] = plugin_data;
};

HTMLEdManager.execute = function ( ed_name, plugin_name, action )
{
	var editor = HTMLEdManager._instances [ ed_name ];
	var plugin = HTMLEdManager._plugins [ plugin_name ];
	var act    = plugin [ 'actions' ] [ action ];

	act [ 1 ] ( editor.iframe.contentWindow.document, editor );

	// console.debug ( act );
};

/*
	This is the generic HTMLEd class, the real interface
	for both Mozilla and IE version of the editor
*/
function HTMLEd ( name, plugins )
{
	this.name	= name;		// Name of the HTMLEditor
	this.plugins	= plugins;

	this.iframe	= null;		// IFrame
	this.doc 	= null;		// ContentWindow.document

	this._div_toolbar = null;
	this._toolbar = null;
	
	this.toolbar_elements = 10;

	this.create_toolbar = function ()
	{
		var plugins = HTMLEdManager._plugins;
		var s = '';
		var cont = 0;
		var _obj = this;

		this._toolbar = new WWL.toolbar ( this.name + ":tbar" );
		
		plugins.iterate ( function ( v, k ) { 
			var pname = k;
			console.debug ( "HTMLed toolbar: plugin name = %s" , pname );
			if ( _obj.plugins && _obj.plugins.indexOf ( pname ) < 0 ) return;

			v [ 'actions' ].iterate ( function ( v, k ) {
				_obj._toolbar.add_item ( { style: "htmled-" + pname + "-" + v [ 2 ], tooltip: v [ 2 ], cback: function () { HTMLEdManager.execute ( _obj.name, pname, k ); } } );
				}  );

				if ( cont > _obj.toolbar_elements )
				{
					cont = 0;
					_obj._toolbar.add_item ( { type: "newline" } );
				}
			}
		);

		this._div_toolbar.innerHTML = this._toolbar.to_string ();
	};

	this.replace = function ( textarea_id, w, h, html_text )
	{
		var txt_area = $( textarea_id );
		var main_div;
		var _obj = this;

		main_div = document.createElement ( "div" );
		main_div.id = this.name + ":main";

		this._div_toolbar = document.createElement ( "div" );
		this._div_toolbar.id = this.name + ":toolbar";
		this._div_toolbar.className = "wwl_htmled";

		this.iframe = document.createElement ( "iframe" );
		this.iframe.htmled = this;	// Save HTMLEd reference into the iframe
		if ( w ) this.iframe.style.width = w + "px";
		if ( h ) this.iframe.style.height = h + "px";

		this.textarea = document.createElement ( 'textarea' );
		this.textarea.htmled = this;	// Save HTMLEd reference into the iframe
		this.textarea.style.display = "none";

		main_div.appendChild ( this._div_toolbar );
		main_div.appendChild ( this.iframe );
		main_div.appendChild ( this.textarea );

		txt_area.parentNode.appendChild ( main_div );
		txt_area.style.display = 'none';

		function _set_design_mode ()
		{
			console.debug ( "Set Design Mode ... ");
			if ( _obj.iframe && _obj.iframe.contentWindow && _obj.iframe.contentWindow.document )
			{
				_obj.doc = _obj.iframe.contentWindow.document;
				_obj.doc.designMode = "on";
				_obj.set_html ( html_text );
			} else
				setTimeout ( _set_design_mode, 400 );
		}
		
		setTimeout ( _set_design_mode, 500 );

		this.create_toolbar ();
	};

	this.remove = function ()
	{
		var div = $( this.name + ":main" );
		if ( ! div ) return;

		div.parentNode.removeChild ( div );
	};

	this.perform = function ( btn )
	{
		var split = btn.split ( "/" );
		this.plugins [ split [ 0 ] ] [ split [ 1 ] ] ();
	};

	this.get_html = function ()
	{
		var s = this.doc.body.innerHTML;

		return s;
	};

	this.set_html = function ( html )
	{
		if ( this.doc )
			this.doc.body.innerHTML = html;
		else {
			console.debug ( "Waiting ... " );
			var _obj = this;
			setTimeout ( function () { _obj.set_html ( html ); }, 300 );
		}
	};


	this.show_html = function ( show )
	{
		var shown = ( this.textarea.style.display == "block" );
		var s;

		if ( typeof show == "undefined" ) show = ! shown;

		if ( show )
		{
			s = this.get_html ();
			this.textarea.value = s;

			this.textarea.style.width = this.iframe.clientWidth + "px";
			this.textarea.style.height = this.iframe.clientHeight + "px";

			this.iframe.style.display = "none";
			this.textarea.style.display = "block";
		}
		else
		{
			s = this.textarea.value;
			this.set_html ( s );

			this.iframe.style.display = "block";
			this.textarea.style.display = "none";
		}
	};
}

function _init_iframe () 
{
	_os3_htmled.set ( _os3_htmled.frame_id );

	var doc = _os3_htmled.doc;

	if (! doc )
	{
		// Try again..
		if ( _os3_htmled.is_gecko) {
			setTimeout ( _init_iframe, 100 );
			return;
		} else {
			alert("ERROR: IFRAME can't be initialized.");
		}
	} else {
		doc.designMode = "on";
		alert ( doc.designMode );
	}
}
